Among UsのMod開発のために通信を確認する
#amongus #mod #開発 #bepinex #c#
AmongUsはオンライン対戦が可能なので、サーバとクライアントで通信が発生する。
他プレイヤーの位置とか、タスクの進行状況、投票の状況などなど、
画面に表示されるすべての情報は他のプレイヤーと共有されてるから、
都度通信が発生している。
ってことで、いつどんなタイミングでどんな通信が発生し、それがどこに反映されるかを確認していきたい。
大まかな登場人物
まずはおおまかな登場人物を洗い出す。
直観的には、サーバとクライアント。
あとクライアントの中の一人がホストを兼ねる。って感じかな?
クライアント側から追いかけてみる
amongusのメソッドをみてると、rpc関連のメソッドにはrpcという名前がついてる傾向にありそう。
まずはその辺を見てみる。
RpcCalls
RpcCalls という byteのenumがある。
みた感じ、どういったメッセージを送るかの種類名に見える。
HandleRpc
MeetingHud とか、 PlayerControl みたいな主要なオブジェクトには、
void HandleRpc(byte callId, MessageReader reader) が含まれてる。
ここを監視すると通信の内容が分かるかも。
RpcXxx
MeetingHud.RpcClearVote とか、 ShipStatus.RpcEndGame とか、
RpcXxxってメソッドがそこかしこにある。
ここを監視すると、通信の内容が分かるかも。
StreamXxx
gRPCしか触ったことないけど、継続的に通信を送り続ける仕組みがあるなら、たぶんstreamという名前がついてるはず。
BroadcastXxx
Streamじゃなくて、Broadcastって名前がついてるかも?
CustomNetworkTransform
CustomNetworkTransform classが通信の色々をやってるかも。
Vector2 を引数や返り値に持っているメソッドがいくつかあるから、
これが叩かれるんだろうなーという印象がある。
PlayerControlが持ってる。
InnerNetClient
InnerNetClient classも通信の色々をやってるかも。
他のclassが持っているRpcXxxが最終的に叩く先かも。
AmongUsClient が継承してる。
この辺のことから、InnerNetClient 、 CustomNetworkTransform 、 RpcXxx あたりにPrefix、Postfixを追加すれば、
各挙動でどんなメソッドが叩かれるかを特定できそう。
ログを仕込んでみたところ、JOINしたときの挙動とかは分かってきた。
が、移動周りだけが分からない。
CustomNetworkTransform でシリアライズしてることは分かるし、
WriterとReaderがあるから位置の通信を変換してるのは間違いなさそう。
これがどこから叩かれているのか。
ちなみに、自キャラが動いたら WriteVector2 が、他キャラが動いたら ReadVector2 が叩かれる。
CustomNetworkTransform 自体はPlayerControlにあるけど、
たぶんPlayerControlを管理できるもっと外側にいるオブジェクトがPlayer一覧舐めながら叩いてると思う。
いや、CustomNetworkTransform に sendIntervalってのがある。
もしかして、値を書き換えたらFixedUpdateで勝手に書き換えられるんじゃ。
https://scrapbox.io/files/61ae57b6f0da4a001d9a3636.mp4
自キャラのtargetSyncPositionがかわってもWriteは叩かれないし、
他キャラのtargetSyncPositionが変わっても当たり前やけどReadは叩かれない。
そもそもInnerNetClientのStartRpcが叩かれないから、RPCを通して他のプレイヤーに送信しているのはここじゃない。
移動のイベントがどっから叩かれてるかはいったんおいといて、
ゲームスタートからエンドまでがどんなイベントによって作られているかを追いかけてみる。
ゲームの流れと発生する通信
ロビーの作成
ゲーム設定の共有: PlayerControl.RpcSyncSettings
プレイヤーの参加
カラー
帽子: PlayerControl.RpcSetHat
スキン: PlayerControl.RpcSetSkin
バイザー: PlayerControl.RpcSetVisor
ペット: PlayerControl.RpcSetPet
ネームプレート: PlayerControl.RpcSetNamePlate
レベル: PlayerControl.RpcSetLevel
名前?
ゲーム設定の変更・共有
#2021/12/05週
更新履歴
#2021/12/06 かきはじめ